The best way to learn a new programming language is by creating some small interesting application. In this tutorial, I will try to cover the basic of Vue Js by making a small interesting Balloon Burst game. It will be useful for beginners who are learning Vue Js. The Vue js is an Upcoming Progressive JavaScript Framework. It is one of the fastest growing Javascript frameworks and also very easy to learn. I am only using VanillaJS and Vue Js for making this game and Bootstrap and some little custom CSS for designing.
The game's logic is very simple. When you click the balloon, the balloon's life will drop by 5% by calling a punch() method on click event and it will regenerate itself after 1 seconds automatically calling the regenerate() method by Javascript native function setInterval() based on the difficulty level you were chosen. A millisecond counter will start when you started the game to track your achievement. This will help you to challenge yourself.
The Complete code of the view page is given below.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Balloon Burst</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="app">
<div class="container">
<div class="row">
<div class="col-md-3 col-md-offset-4">
<p> </p>
<h2 class="text-center">Balloon Burst</h2>
<div id="balloon" v-on:click="punch" v-bind:class="{burst: ended}"
title="Click Here To Punch The Balloon"></div>
<div id="health">
<div v-bind:style="{ width: health+'%'}"></div>
</div>
<div id="timer" class="text-center">
<label >Time : {{ seconds }} s</label>
</div>
<hr>
<div id="difficulty" class="text-center">
<label class="radio-inline">
<input type="radio" v-model="level" value="1" title="Regeration 1+" checked>Low
</label>
<label class="radio-inline">
<input type="radio" v-model="level" value="5" title="Regeration 5+" >Medium
</label>
<label class="radio-inline">
<input type="radio" v-model="level" value="10" title="Regeration 10+" >High
</label>
</div>
<hr>
<div id="controls">
<button v-on:click="start" v-show="!ended" class="btn btn-success" >Start</button>
<button v-on:click="restart" class="btn btn-danger">Restart</button>
</div>
<div id="audio">
<audio ref="audio" volume="1" preload="auto">
<source src="pop.mp3">
</audio>
</div>
</div> <!-- end of .col-md-3.col-md-offset-4 -->
</div> <!-- end of .row -->
</div> <!-- end of .container -->
</div> <!-- end of #app -->
</body>
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script type="text/javascript" src="main.js"></script>
</html>
The balloon div container contains our balloon. Initially, it will not have burst class embedded to it as the value of ended data is false. When the value of the health data becomes 0 then the ended will become true and the balloon div container will get burst class embedded to it. The seconds is one way bound and it will show game duration in seconds with up to 3 decimal points.
The radio button is used to select the difficulty levels of the game. Initially, it will be set to low. Based on user choice he can increase or decrease difficulty level. At the low level, the balloon's life will regenerate only 1% each second and at the medium level, the balloon's life will regenerate 5% every second and at the high level, the balloon's life will regenerate 10% every second.The start button will call the start method to start the game and restart button calls the restart method and restarts the game.
Now let's see the codes inside the main.js file.
var app = new Vue({
el: "#app",
data: {
health:100,
level: 1,
started: false,
ended: false,
startTime: "",
elapsedTime: "",
seconds: "00",
},
methods:{
start : function(){
self = this;
this.startTime = Date.now();
this.started = true;
setInterval(function(){
self.regenerate();
}, 1000);
setInterval(function(){
self.countTimer();
}, 100);
},
punch: function(){
if(this.started == true)
{
this.health -= 5;
if(this.health <= 0){
this.ended = true;
this.$refs.audio.play();
}
}else{
alert("Game Not Yet Started !");
}
},
regenerate: function(){
if(this.health <= 90 && this.ended == false)
{
this.health += parseInt(this.level);
}
},
restart: function(){
this.health = 100;
this.ended = false;
this.started = false;
this.seconds = "00";
this.startTime = "";
this.elapsedTime = "";
},
countTimer: function() {
if(this.started == true && this.ended == false)
{
this.elapsedTime = Date.now() - this.startTime;
this.seconds = (this.elapsedTime / 1000).toFixed(3);
}
},
},
});
Since the Javascript is single threaded in nature, A timer event may not occur exactly at the right time interval so we call to Date.now() will always give you the exact current system time. So, Always use something like Date.now() to get the current time and compare it to some previous time to calculate the actual elapsed time. This will be as accurate as the system clock on the computer.
When the game ended a burst sound will produce by calling our hidden HTML audio player using $ref. The special attribute ref is used to register a reference to an element or a child component. The reference will be registered under the parent component’s $refs object.
Since the radio buttons value attribute will only give value in string format we need to convert it into integer format by using javascript native parseInt() Function. The parseInt() function parses a string and returns an integer. The toFixed() method converts a number into a string, keeping a specified number of decimals.
Note : After Each Restart the game speed increases as the Regeneration time increases. This is happening because on each start button click the regenerate and countTimer functions calls again too. To avoid this you can call these function from mounted function thus these function only initiated once when componets become ready. Here is the syntax for that, Put this after methods.
mounted: function(){
setInterval(function(){
self.regenerate();
}, 1000);
setInterval(function(){
self.countTimer();
}, 100);
}
Now finally let's improve the look and feel of our application. The codes in the style.css file are given below.
h2{
font-family: Merriweather,serif;
font-weight: bolder;
}
#balloon{
width: 100%;
height: 300px;
margin : 0 auto;
background: url(balloon.png) center no-repeat;
background-size: 80%;
border: 2px solid #000;
}
#balloon.burst{
background: url(balloon-burst.png) center no-repeat;
}
#health{
width: 100%;
border: 2px solid #000;
margin : 20px auto 20px auto;
}
#health div{
height: 20px;
background: red;
}
#controls{
width: 100%;
margin: 20px auto;
text-align: center;
}
#audio{
display: none;
}
The balloon div will have a background image of a balloon and balloon div with class burst will have a div with the background image of a busted balloon.
The output image of above program is given below.
DEMO
You can demo the above game by visiting following link.
https://shareurcodes.com/demo/balloon/
If anybody has any suggestions or doubts or need any help comment below and I try will respond to every one of you as early as possible.